package com.xbongbong.paas.connection.connector.help;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.connection.enums.BusinessCodePrefixEnum;
import com.xbongbong.paas.connection.pojo.connector.AddressCommonPojo;
import com.xbongbong.paas.connection.pojo.connector.PhoneCommonPojo;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.AddressEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.ProErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

@Service("connectorHelper")
public class ConnectorHelper {
    @Resource
    private CustomerModel customerModel;
    @Resource
    private UserModel userModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private IndexTypeModel indexTypeModel;

    /**
     * 获取关联客户json
     * @param corpid 公司id
     * @param customerNumber 客户id的字符串
     * @return {"id":1, "name":"张三"}
     * @throws XbbException
     * 创建时间 2021/5/28 2:02 PM
     * 修改时间 2021/5/28 2:02 PM
     * @author chy
     */
    public JSONObject getCustomerObject(String corpid, String customerNumber) throws XbbException {
        Long customerId = getCustomerId(corpid, customerNumber);

        if (Objects.isNull(customerId)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, "customerNumber异常");
        }
        CustomerEntityExt customer = customerModel.getByKey(customerId, corpid);
        if (Objects.isNull(customer)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404, "客户不存在或已删除");
        }
        JSONObject data = customer.getData();
        String customerName = data.getString(CustomerManagementEnum.NAME.getAttr());
        JSONObject customerJson = new JSONObject();
        customerJson.put("id", customerId);
        customerJson.put("name", customerName);
        return customerJson;
    }

    /**
     * 通过客户编码获取客户id
     * @param corpid
     * @param customerNumber 客户编码，现在销帮帮这边传过去的编码格式为 XBB_CU. + 客户id
     * @return
     * 创建时间 2021/6/23 2:15 PM
     * 修改时间 2021/6/23 2:15 PM
     * @author chy
     */
    private Long getCustomerId(String corpid, String customerNumber) throws XbbException {
        if (StringUtil.isEmpty(customerNumber)) {
            return null;
        }
        Long customerId = null;
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(BasicConstant.SERIAL_NO + ".keyword", customerNumber));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        List<String> fieldList = new ArrayList<>();
        fieldList.add(StringConstant.DATA_ID);
        IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = esHelper.findByScroll(indexTypeEnum,boolQueryBuilder,PaasFormDataEntityExt.class,fieldList);
        if (Objects.nonNull(paasFormDataEntityExtList)) {
            customerId = paasFormDataEntityExtList.get(0).getDataId();
        } else {
            String customerIdStr = customerNumber.replaceFirst(BusinessCodePrefixEnum.CUSTOMER_CODE_PREFIX.getPrefix(), "");
            customerId = Long.parseLong(customerIdStr);
        }
        return customerId;
    }

    /**
     * 员工多选
     * @param corpid
     * @param userId
     * @return [{"id":"1", "name":"张杰"}]
     * 创建时间 2021/5/28 2:46 PM
     * 修改时间 2021/5/28 2:46 PM
     * @author chy
     */
    public JSONArray getUserArray(String corpid, String userId) throws XbbException {
        return getUserArray(corpid, Arrays.asList(userId));
    }

    /**
     * 员工多选
     * @param corpid
     * @param userIdList
     * @return [{"id":"1", "name":"张杰"}]
     * 创建时间 2021/5/28 2:46 PM
     * 修改时间 2021/5/28 2:46 PM
     * @author chy
     */
    public JSONArray getUserArray(String corpid, List<String> userIdList) throws XbbException {
        List<UserEntity>  userList = userModel.getByUserIdIn(corpid, userIdList, true);
        JSONArray userArray = new JSONArray();
        for (UserEntity user : userList) {
            if (Objects.isNull(user)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, "empNumber异常");
            }
            if (Objects.isNull(user)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100004);
            }
            JSONObject userJson = new JSONObject();
            userJson.put("id", user.getUserId());
            userJson.put("name", user.getName());
            userArray.add(userJson);
        }
        return userArray;
    }

    /**
     * 员工单选
     * @param corpid
     * @param userId
     * @return {"id":"1", "name":"张杰"}
     * 创建时间 2021/5/28 2:46 PM
     * 修改时间 2021/5/28 2:46 PM
     * @author chy
     */
    public JSONObject getUserObject(String corpid, String userId) throws XbbException {
        if (StringUtil.isEmpty(userId)) {
            return null;
        }
        UserEntity user =  userModel.getByKey(userId, corpid);
        if (Objects.isNull(user)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100004.getCode(), "用户不存在，corpid:" + corpid + " userId:" + userId);
        }
        JSONObject userObject = new JSONObject();
        userObject.put("id", user.getUserId());
        userObject.put("name", user.getName());
        return userObject;
    }

    /**
     * 通过编号获取合同集合
     * @param corpid
     * @param contractSerialNoList
     * @return
     * @throws XbbException
     */
    public JSONArray getContractArrayBySerialNo(String corpid,  List<String> contractSerialNoList) throws XbbException {
        JSONArray contractArray = new JSONArray();
        if (Objects.isNull(contractSerialNoList) || contractSerialNoList.isEmpty()) {
            return contractArray;
        }
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termsQuery(ContractEnum.CONTRACT_NO.getAttr() + ".keyword", contractSerialNoList));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        List<String> fieldList = new ArrayList<>();
        fieldList.add(StringConstant.DATA_ID);
        fieldList.add(ContractEnum.CONTRACT_NO.getAttr());
        fieldList.add(ContractEnum.getAttrConnectData(ContractEnum.LINK_CUSTOMER));
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CONTRACT,boolQueryBuilder,PaasFormDataEntityExt.class,fieldList);
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExtList) {
            String serialNo = paasFormDataEntityExt.getSerialNo();
            Long dataId = paasFormDataEntityExt.getDataId();
            JSONObject contractJson = new JSONObject();
            contractJson.put("id", dataId.toString());
            contractJson.put("name", serialNo);
            contractArray.add(contractJson);
        }
        return contractArray;
    }

    /**
     * 将选项文本转化成选项Object
     * @param fieldAttrEntity
     * @param comboText
     * @return
     * @throws XbbException
     */
    public JSONObject getComboObject(FieldAttrEntity fieldAttrEntity, String comboText) throws XbbException {
        List<ItemPoJo> items = fieldAttrEntity.getItems();
        return getComboObject(items, comboText);
    }

    /**
     * 将选项文本转化成选项Object
     * @param items
     * @param comboText
     * @return
     */
    public JSONObject getComboObject(List<ItemPoJo> items, String comboText) throws XbbException {
        JSONObject retObject = new JSONObject();
        for (ItemPoJo item : items) {
            String text = item.getText();
            if (Objects.equals(comboText, text)) {
                String value = item.getValue().toString();
                retObject.put("text", text);
                retObject.put("value", value);
                return retObject;
            }
        }
        if (retObject.size() == 0) {
            if (hasOtherOption(items)) {
                retObject.put("text", comboText);
                retObject.put("value", comboText);
            } else {
                throw new XbbException(ProErrorCodeEnum.API_ERROR_701041);
            }
        }
        return retObject;
    }

    /**
     * 判断是否有其他选项
     * @param items
     * @return
     */
    private boolean hasOtherOption(List<ItemPoJo> items) {
        for (ItemPoJo item : items) {
            if (Objects.equals(item.getIsOther(), 1)) {
                return true;
            }
        }
        return false;
    }

    public JSONObject getAddressFormat(AddressCommonPojo address) {
        String province = address.getProvince();
        String city = address.getCity();
        String district = address.getDistrict();
        String detailAddress = address.getDetailAddress();
        JSONObject addressJson = new JSONObject();
        addressJson.put(AddressEnum.PROVINCE.getAlias(), province);
        addressJson.put(AddressEnum.CITY.getAlias(), city);
        addressJson.put(AddressEnum.DISTRICT.getAlias(), district);
        addressJson.put(AddressEnum.ADDRESS.getAlias(), detailAddress);
        return addressJson;
    }

    public JSONArray getPhoneFormat(FieldAttrEntity fieldAttr, List<PhoneCommonPojo> phoneList) throws XbbException {
        List<? extends FieldAttrEntity> subExplainList = fieldAttr.getSubForm().getItems();
        Map<String, FieldAttrEntity> subExplainMap = ExplainUtil.getExplainMapByList(subExplainList);
        JSONArray phoneArray = null;
        if (Objects.nonNull(phoneList)) {
            phoneArray = new JSONArray();
            FieldAttrEntity subFieldAttr = subExplainMap.get("text_1");
            List<ItemPoJo> items = subFieldAttr.getItems();
            for (PhoneCommonPojo phone : phoneList) {
                String type = phone.getType();
                String value = phone.getValue();
                String typeCode = getComboValue(items, type);
                JSONObject phoneJson = new JSONObject();
                phoneJson.put("text_1", typeCode);
                phoneJson.put("text_2", value);
                phoneArray.add(phoneJson);
            }
        }
        return phoneArray;
    }

    /**
     * 通过选项文本获取选项值
     * @param items
     * @param text
     * @return
     * @throws XbbException
     */
    public String getComboValue(List<ItemPoJo> items, String text) throws XbbException {
        if (StringUtil.isEmpty(text)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, "选项参数异常");
        }
        String value = null;
        for (ItemPoJo item : items) {
            if (Objects.equals(item.getText(), text)) {
                value = item.getValue().toString();
                continue;
            }
        }
        if (StringUtil.isEmpty(value) && hasOtherOption(items)) {
            value = text;
        }
        return value;
    }

    /**
     * 获取解释map
     * @param corpid
     * @param formId
     * @return
     * @throws XbbException
     */
    public Map<String, FieldAttrEntity> getExpainMap(String corpid, Long formId) throws XbbException {
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        Map<String, FieldAttrEntity> explainMap = new HashMap<>();
        explainList.forEach(item -> {
            explainMap.put(item.getAttr(), item);
        });
        return explainMap;
    }
}
